#region using
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml;
using Microsoft.Win32;
using Microsoft.MediaCenter;
using Microsoft.MediaCenter.Hosting;
using Microsoft.MediaCenter.UI;
using Microsoft.MediaCenter.TV.Scheduling;

using UTorrentLib;

#endregion

namespace MCEMediaManager
{
    public class Application : ModelItem, IDisposable
    {
        #region Private Properties
        private static Application _SingleApplicationInstance;
        private AddInHost _Host;
        private ExtendedPageSession _Session;
        private Torrents _TorrentList;
        private FilteredContentPage _DiscoverContentPage;
        private Dictionary<string, IMediaPlugin> _MediaPlugins;
        private bool _IsBusy = false;
        private string _SharedDirectory = null;
        private ApplicationDataStore _Data = null;
        private string _AppVersion;
        private TVDB _TVDBData;
        #endregion

        #region Public Properties
        public FilteredContentPage DiscoverContentPage
        {
            get 
            {
                if (_DiscoverContentPage == null)
                    _DiscoverContentPage = CreateDiscoverContentPage();
                return (this._DiscoverContentPage); 
            }
            set { this._DiscoverContentPage = value; }
        }

        public Torrents TorrentList
        {
            get { return this._TorrentList; }
            set { this._TorrentList = value; }
        }

        //public MyEpg EpgData
        //{
        //    get { return (this._EpgData); }
        //    set { this._EpgData = value; }
        //}

        public TVDB TVDBData
        {
            get { return (this._TVDBData); }
            set { this._TVDBData = value; }
        }

        /// <summary>
        /// The Media Center environment.
        /// </summary>
        public MediaCenterEnvironment MediaCenterEnvironment
        {
            get
            {
                if (_Host == null)
                    return null;

                return _Host.MediaCenterEnvironment;
            }
        }

        public Dictionary<string, IMediaPlugin> MediaPlugins
        {
            get
            {
                if(_MediaPlugins == null)
                {
                    _MediaPlugins = GetMediaPlugins();
                }
                return this._MediaPlugins;
            }
            set{ this._MediaPlugins = value; }
        }

        public RegistryKey RootRegKey
        {
            get
            {
                RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\MCE Media Manager");
                if (key == null)
                    key = Registry.LocalMachine.CreateSubKey("SOFTWARE\\MCE Media Manager");
                return key;
            }
        }

        public bool IsBusy
        {
            get { return (this._IsBusy); }
            set 
            {
                if (this._IsBusy != value)
                {
                    Debug.WriteLine("Changing IsBusy to " + _IsBusy);
                    this._IsBusy = value;
                    FirePropertyChanged("IsBusy");
                }
            }
        }

        public static Application Current
        {
            get
            {
                return _SingleApplicationInstance;
            }
        }

        public string SharedDirectory
        {
            get
            {
                if (_SharedDirectory == null)
                {
                    _SharedDirectory = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\MCE Media Manager\";
                }
                return _SharedDirectory;
            }
        }

        public ApplicationDataStore DataStore
        {
            get
            {
                if (_Data == null)
                    _Data = new ApplicationDataStore();
                return _Data;
            }
        }
		public String DisplayVersion 
        { 
            get 
            { 
                if (_AppVersion == String.Empty) 
                { 
                    try 
                    { 
                        _AppVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); 
                    } 
                    catch (Exception) 
                    { 
                        _AppVersion = String.Empty; 
                    } 
                } 
                return String.Format("MCE Media Manager v{0}", (_AppVersion == String.Empty) ? "Unknown" : _AppVersion); 
            } 
        } 
		#endregion

        #region Constructors
        public Application()
            : this(null, null)
        {

        }

        public Application(ExtendedPageSession session, AddInHost host)
        {
            this._Host = host;
            this._Session = session;
            _SingleApplicationInstance = this;
            this._TorrentList = new Torrents();
            this._Data = new ApplicationDataStore();
            this._TVDBData = new TVDB();
            Debug.WriteLine(this.MediaPlugins.Count);
            //this._EpgData.LoadEpg(true, true);
            
        }
        #endregion

        #region GoTo Methods
        public void GoToStartPage()
        {
            //_Session.GoToPage("resx://MCEMediaManager/MCEMediaManager.Resources/Default");
            //GoToDiscoverContentPage();
            GoToMediaSearchPage();
            //GoToTorrentList(TorrentList.CreateListPage());
        }

        public void GoToDiscoverContentPage()
        {
            bool busy = IsBusy;
            IsBusy = true;

            // If we have no page session, just spit out a trace statement.
            if (_Session == null)
            {
                Debug.WriteLine("GoToTorrentList: " + DiscoverContentPage.Description);
                IsBusy = busy;
                return;
            }


            //
            // Construct the arguments dictionary and then navigate to the
            // gallery page template.
            //

            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["Page"] = DiscoverContentPage;
            properties["Application"] = this;

            IsBusy = busy;
            _Session.GoToPage("resx://MCEMediaManager/MCEMediaManager.Resources/DiscoverContent", properties);
            
        }

        public void GoToTorrentList(TorrentListPage page)
        {
            if (page == null)
            {
                page = TorrentList.CreateListPage();
            }

            // If we have no page session, just spit out a trace statement.
            if (_Session == null)
            {
                Debug.WriteLine("GoToTorrentList: " + page.Description);
                return;
            }


            //
            // Construct the arguments dictionary and then navigate to the
            // gallery page template.
            //

            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["Page"] = page;
            properties["Application"] = this;

            _Session.GoToPage("resx://MCEMediaManager/MCEMediaManager.Resources/TorrentList", properties);
        }

        public void GoToMediaSearchPage()
        {
            SearchContentPage page = CreateMediaSearchPage();

            // If we have no page session, just spit out a trace statement.
            if (_Session == null)
            {
                Debug.WriteLine("GoToMediaSearchPage: " + page.Description);
                return;
            }

            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["Page"] = page;
            properties["Application"] = this;

            _Session.GoToPage("resx://MCEMediaManager/MCEMediaManager.Resources/SearchMedia", properties);

        }

        public void GoToMediaSearchResultsPage(DualFilteredContentPage resultsPage, SearchContentPage searchPage)
        {
            if (resultsPage == null)
                throw new ArgumentException("page", "Must specify page");

            // If we have no page session, just spit out a trace statement.
            if (_Session == null)
            {
                Debug.WriteLine("GoToMediaSearchResultsPage: " + resultsPage.Description);
                return;
            }


            //
            // Construct the arguments dictionary and then navigate to the
            // gallery page template.
            //

            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["Page"] = resultsPage;
            properties["Application"] = this;
            properties["SearchString"] = searchPage.SearchText;

            _Session.GoToPage("resx://MCEMediaManager/MCEMediaManager.Resources/SearchMediaResults", properties);
        }

        public void GoToAddTorrentPage()
        {
            GoToAddTorrentPage("");
        }

        public void GoToAddTorrentPage(string searchText)
        {
            TorrentSearchPage page = TorrentList.CreateSearchPage();

            // If we have no page session, just spit out a trace statement.
            if (_Session == null)
            {
                Debug.WriteLine("GoToAddTorrent: " + page.Description);
                return;
            }
            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties["Page"] = page;
            properties["Application"] = this;
            if (searchText != "")
            {
                EditableText text = new EditableText();
                text.Value = searchText;
                properties["EditableText"] = text;
            }

            _Session.GoToPage("resx://MCEMediaManager/MCEMediaManager.Resources/AddTorrent", properties);
        }

        #endregion

        #region Create Methods
        public DualFilteredContentPage CreateDiscoverContentPage()
        {
            DualFilteredContentPage resultsPage = new DualFilteredContentPage();
            resultsPage.Description = "discover content";

            ArrayListDataSet categorylist = new ArrayListDataSet(resultsPage);
            CustomChoice categories = new CustomChoice(resultsPage, "Categories", categorylist);
            IMediaPlugin dummyPlugin = new MediaPlugin();
            dummyPlugin.Name = "Searching...";
            dummyPlugin.DiscoverContentLabel = "Searching...";
            categories.Options.Add(dummyPlugin);

            ArrayListDataSet filterlist = new ArrayListDataSet(resultsPage);
            filterlist.Add("All");
            Choice filters = new Choice(resultsPage, "Filters", filterlist);
            filters.Chosen = "All";

            resultsPage.ActiveCategoryChanged += delegate(object sender, EventArgs e)
            {
                DualFilteredContentPage theResultsPage = (DualFilteredContentPage)sender;
                string activeCategory = "";
                if (((IMediaPlugin)theResultsPage.Categories.Chosen) != null)
                    activeCategory = ((IMediaPlugin)theResultsPage.Categories.Chosen).Name;
                if (activeCategory == "Searching..." || activeCategory == "")
                {
                    resultsPage.Filters = new Choice(theResultsPage, "Filters", new ArrayListDataSet(resultsPage));
                }
                else
                {
                    Choice newFilters = new Choice(theResultsPage, "Filters", Application.Current.MediaPlugins[activeCategory].Filters);
                    resultsPage.Filters = newFilters;
                }
            };

            resultsPage.ActiveFilterChanged += delegate(object sender, EventArgs e)
            {
                DualFilteredContentPage theResultsPage = (DualFilteredContentPage)sender;
                string activeCategory = "";
                if (((IMediaPlugin)theResultsPage.Categories.Chosen) != null)
                    activeCategory = ((IMediaPlugin)theResultsPage.Categories.Chosen).Name;
                string activeFilter = "All";
                if (theResultsPage.Filters.Chosen != null)
                    activeFilter = theResultsPage.Filters.Chosen.ToString();
                if (activeCategory == "Searching..." || activeCategory == "" || activeCategory == null)
                {
                    theResultsPage.Content = new ArrayListDataSet();
                }
                else
                {
                    theResultsPage.Content = MediaPlugins[activeCategory].GetDiscoveryItems(activeFilter);
                }
            };
            resultsPage.Filters = filters;
            resultsPage.Categories = categories;

            foreach (IMediaPlugin tempPlugin in MediaPlugins.Values)
            {
                if (tempPlugin.HasDiscoveryInterface)
                {
                   Microsoft.MediaCenter.UI.Application.DeferredInvokeOnWorkerThread(
                        new DeferredHandler(tempPlugin.CreateDiscoveryItems),
                        new DeferredHandler(DiscoverContentComplete),
                        new SearchArgs(null, resultsPage, tempPlugin));
                }
            }
            return resultsPage;
        }

        public SearchContentPage CreateMediaSearchPage()
        {
            SearchContentPage mediaSearchPage = new SearchContentPage();
            mediaSearchPage.Description = "search : media";

            ArrayListDataSet mediaList = new ArrayListDataSet(mediaSearchPage);
            mediaList.Add(new MediaItem());

            mediaSearchPage.Content = mediaList;
            mediaSearchPage.SearchTextChanged += delegate(object sender, EventArgs e)
            {
                SearchContentPage page = (SearchContentPage)sender;
                if (page.SearchText != "" && page.SearchText != null)
                    SearchMedia(page);
            };

            return mediaSearchPage;
        }

        public DualFilteredContentPage CreateMediaSearchResultsPage()
        {
            DualFilteredContentPage resultsPage = new DualFilteredContentPage();
            resultsPage.Description = "search : media";

            ArrayListDataSet categorylist = new ArrayListDataSet(resultsPage);
            CustomChoice categories = new CustomChoice(resultsPage, "Categories", categorylist);
            IMediaPlugin dummyPlugin = new MediaPlugin();
            dummyPlugin.Name = "Searching...";
            dummyPlugin.SearchLabel = "Searching...";
            categories.Options.Add(dummyPlugin);

            ArrayListDataSet filterlist = new ArrayListDataSet(resultsPage);
            filterlist.Add("All");
            Choice filters = new Choice(resultsPage, "Filters", filterlist);
            filters.Chosen = "All";

            resultsPage.ActiveCategoryChanged += delegate(object sender, EventArgs e)
            {
                DualFilteredContentPage theResultsPage = (DualFilteredContentPage)sender;
                string activeCategory = "";
                if (((IMediaPlugin)theResultsPage.Categories.Chosen) != null)
                    activeCategory = ((IMediaPlugin)theResultsPage.Categories.Chosen).Name;
                if (activeCategory == "Searching..." || activeCategory == "")
                {
                    theResultsPage.Filters = new Choice(theResultsPage, "Filters", new ArrayListDataSet(resultsPage));
                }
                else
                {
                    Choice newFilters = new Choice(theResultsPage, "Filters", Application.Current.MediaPlugins[activeCategory].Filters);
                    theResultsPage.Filters = newFilters;
                }
            };

            resultsPage.ActiveFilterChanged += delegate(object sender, EventArgs e)
            {
                DualFilteredContentPage theResultsPage = (DualFilteredContentPage)sender;
                string activeCategory = "";
                if (((IMediaPlugin)theResultsPage.Categories.Chosen) != null)
                    activeCategory = ((IMediaPlugin)resultsPage.Categories.Chosen).Name;
                string activeFilter = "All";
                if (theResultsPage.Filters.Chosen != null)
                    activeFilter = theResultsPage.Filters.Chosen.ToString();
                if (activeCategory == "Searching..." || activeCategory == "" || activeCategory == null)
                {
                    theResultsPage.Content = new ArrayListDataSet();
                }
                else
                {
                    theResultsPage.Content = Application.Current.MediaPlugins[activeCategory].GetSearchResults(activeFilter);
                }
            };
            resultsPage.Filters = filters;
            resultsPage.Categories = categories;

            return resultsPage;
        }
        public FilteredContentPage CreateTVListingPage()
        {
            FilteredContentPage resultsPage = new FilteredContentPage();
            resultsPage.Description = "tv";

            ArrayListDataSet filterlist = new ArrayListDataSet(resultsPage);
            filterlist.Add("All");
            Choice filters = new Choice(resultsPage, "Filters", filterlist);
            filters.Chosen = "All";

            resultsPage.ActiveFilterChanged += delegate(object sender, EventArgs e)
            {
                FilteredContentPage theResultsPage = (FilteredContentPage)sender;
                string activeFilter = "All";
                if (theResultsPage.Filters.Chosen != null)
                    activeFilter = theResultsPage.Filters.Chosen.ToString();
                //theResultsPage.Content = MediaPlugins[activeCategory].GetDiscoveryItems(activeFilter);
            };
            resultsPage.Filters = filters;

            foreach (IMediaPlugin tempPlugin in MediaPlugins.Values)
            {
                if (tempPlugin.HasTVInterface)
                {
                    Microsoft.MediaCenter.UI.Application.DeferredInvokeOnWorkerThread(
                         new DeferredHandler(tempPlugin.CreateTVItems),
                         new DeferredHandler(DiscoverContentComplete),
                         new SearchArgs(null, resultsPage, tempPlugin));
                }
            }
            return resultsPage;
        }
        #endregion

        #region Methods
        public void MessageBox(string text, string caption, int timeout, bool modal)
        {
            if (_Host == null)
            {
                Debug.WriteLine(String.Format("Dialog {0}: {1}", caption, text));
                return;
            }

            _Host. MediaCenterEnvironment.Dialog(
                text,
                caption,
                new object[] { DialogButtons.Ok },
                timeout,
                modal,
                null,
                delegate(DialogResult dialogResult) { });
        }

        public void SearchMedia(SearchContentPage searchPage)
        {
            DualFilteredContentPage resultsPage = CreateMediaSearchResultsPage();
            SearchMedia(searchPage, resultsPage);
        }

        public void SearchMedia(SearchContentPage searchPage, DualFilteredContentPage resultsPage)
        {
            foreach (IMediaPlugin mediaPlugin in MediaPlugins.Values)
            {
                if (mediaPlugin.HasSearchInterface)
                {
                    Microsoft.MediaCenter.UI.Application.DeferredInvokeOnWorkerThread(
                        new DeferredHandler(mediaPlugin.SearchByName),
                        new DeferredHandler(SearchComplete),
                        new SearchArgs(searchPage, resultsPage, mediaPlugin));
                    //mediaPlugin.SearchByName(searchPage.SearchText);
                    //SearchComplete(mediaPlugin, resultsPage);
                }

            }
            GoToMediaSearchResultsPage(resultsPage, searchPage);
        }
        

        private void SearchComplete(object obj)
        {
            SearchArgs args = (SearchArgs) obj;
            bool changeCategory = false;
            DualFilteredContentPage resultsPage = ((DualFilteredContentPage)args.ResultsPage);
            if (resultsPage.Categories.Options.Count == 1 && ((MediaPlugin)resultsPage.Categories.Options[0]).SearchLabel == "Searching...")
            {
                changeCategory = true;
            }
            //if (changeCategory)
            resultsPage.Categories.Options.Add(args.CurrentMediaPlugin);
            //else
            //{
            //    int index = 0;
            //    foreach (IMediaPlugin thePlugin in args.ResultsPage.Categories.Options)
            //    {
            //        if (args.CurrentMediaPlugin.SearchResultsCount > thePlugin.SearchResultsCount)
            //        {
            //            args.ResultsPage.Categories.Options.Insert(index, args.CurrentMediaPlugin);
            //            if (index == 0)
            //                args.ResultsPage.Categories.Chosen = args.ResultsPage.Categories.Options[0];
            //            break;
            //        }
            //        index++;
            //    }
            //}
            if (changeCategory)
            {
                resultsPage.Categories.Chosen = args.CurrentMediaPlugin;
                resultsPage.Categories.Options.RemoveAt(0);
                resultsPage.Categories.Chosen = args.CurrentMediaPlugin;
            }
        }

        public void DiscoverContentComplete(object obj)
        {
            DualFilteredContentPage discoveredContentPage = (DualFilteredContentPage)((SearchArgs)obj).ResultsPage;
            IMediaPlugin currentMediaPlugin = ((SearchArgs)obj).CurrentMediaPlugin;
            bool changeCategory = false;
            if (discoveredContentPage.Categories.Options.Count == 1 && ((MediaPlugin)discoveredContentPage.Categories.Options[0]).DiscoverContentLabel == "Searching...")
            {
                changeCategory = true;
            }
            discoveredContentPage.Categories.Options.Add(currentMediaPlugin);
            if (changeCategory)
            {
                discoveredContentPage.Categories.Chosen = currentMediaPlugin;
                discoveredContentPage.Categories.Options.RemoveAt(0);
                discoveredContentPage.Categories.Chosen = currentMediaPlugin;
            }
        }

        public void TVContentComplete(object obj)
        {
            FilteredContentPage tvContentPage = (FilteredContentPage)((SearchArgs)obj).ResultsPage;
            IMediaPlugin currentTVPlugin = ((SearchArgs)obj).CurrentMediaPlugin;

        }

        public Dictionary<string, IMediaPlugin> GetMediaPlugins()
        {
            IsBusy = true;
            Dictionary<string, IMediaPlugin> theList = new Dictionary<string, IMediaPlugin>();
            //IMediaPlugin tempPlugin = new MeeVeePlugin();
            //theList.Add(tempPlugin.Name, tempPlugin);

            string[] plugins = Application.Current.DataStore.GetString("PluginList", "MCEMediaManager.RecordedTVPlugin;MCEMediaManager.TVRssPlugin;MCEMediaManager.NetflixPlugin;MCEMediaManager.EpgPlugin;MCEMediaManager.HuluPlugin").Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string plugin in plugins)
            {
                try
                {
                    IMediaPlugin mediaPlugin = LoadPluginDynamically(plugin);
                    theList.Add(mediaPlugin.Name, mediaPlugin);
                }
                catch (Exception ex)
                {
                    MessageBox("Error Loading Plugin " + plugin + " : " + ex.Message, "MCE Media Manager Error", 3, false);
                }
            }
            //IMediaPlugin tvrssPlugin = new TVRssPlugin();
            //theList.Add(tvrssPlugin.Name, tvrssPlugin);
            //IMediaPlugin netflixPlugin = new NetflixPlugin();
            //if (((NetflixPlugin)netflixPlugin).CurrentAccessToken != null)
            //    theList.Add(netflixPlugin.Name, netflixPlugin);
            //IMediaPlugin epgPlugin = new EpgPlugin();
            //theList.Add(epgPlugin.Name, epgPlugin);
            //IMediaPlugin huluPlugin = new HuluPlugin();
            //theList.Add(huluPlugin.Name, huluPlugin);
            IsBusy = false;
            return theList;
        }

        public IMediaPlugin LoadPluginDynamically(string pluginString)
        {
            Type type = Type.GetType(pluginString, true);
            object newInstance = Activator.CreateInstance(type);
            return newInstance as IMediaPlugin;
        }

        public void LoadMediaPlugins(object obj)
        {

        }

        public void CompleteLoadMediaPlugins(object obj)
        {
        }

        public CreateScheduleRequestResult RecordShow(string overallDescription, string programTitle, string serviceCallSign, DateTime startTime, bool isRecurring, out ScheduleRequest request)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "utf-8", String.Empty));
            XmlElement clickToRecord = xmlDoc.CreateElement("clickToRecord", "urn:schemas-microsoft-com:ehome:clicktorecord");
            XmlElement body = xmlDoc.CreateElement("body", "urn:schemas-microsoft-com:ehome:clicktorecord");

            //The metaData element
            XmlElement metaData = xmlDoc.CreateElement("metadata", "urn:schemas-microsoft-com:ehome:clicktorecord");
            metaData.AppendChild(xmlDoc.CreateElement("description", "urn:schemas-microsoft-com:ehome:clicktorecord"));
            metaData.ChildNodes[0].InnerText = overallDescription;
            body.AppendChild(metaData);
            
            //The programRecord Element
            XmlElement programRecord = xmlDoc.CreateElement("programRecord", "urn:schemas-microsoft-com:ehome:clicktorecord");
            programRecord.SetAttribute("isRecurring", (isRecurring) ? "true" : "false");
            programRecord.SetAttribute("allowAlternateServices", "true");

            if (programTitle != "")
            {
                XmlElement program = xmlDoc.CreateElement("program", "urn:schemas-microsoft-com:ehome:clicktorecord");
                XmlElement programKey = xmlDoc.CreateElement("key", "urn:schemas-microsoft-com:ehome:clicktorecord");
                programKey.SetAttribute("field", "urn:schemas-microsoft-com:ehome:epg:program#title");
                programKey.SetAttribute("match", "exact");
                programKey.InnerText = programTitle;
                program.AppendChild(programKey);
                programRecord.AppendChild(program);
            }

            if (serviceCallSign != "")
            {
                XmlElement service = xmlDoc.CreateElement("service", "urn:schemas-microsoft-com:ehome:clicktorecord");
                XmlElement serviceKey = xmlDoc.CreateElement("key", "urn:schemas-microsoft-com:ehome:clicktorecord");
                serviceKey.SetAttribute("field", "urn:schemas-microsoft-com:ehome:epg:service#callsign");
                serviceKey.SetAttribute("match", "exact");
                serviceKey.InnerText = serviceCallSign;
                service.AppendChild(serviceKey);
                programRecord.AppendChild(service);
            }

            if (startTime != null)
            {
                Debug.WriteLine(startTime.Kind.ToString());
                XmlElement airing = xmlDoc.CreateElement("airing", "urn:schemas-microsoft-com:ehome:clicktorecord");
                airing.SetAttribute("timeZone", Convert.ToString(TimeZone.CurrentTimeZone.GetUtcOffset(startTime).Hours * 60));
                XmlElement airingKey = xmlDoc.CreateElement("key", "urn:schemas-microsoft-com:ehome:clicktorecord");
                airingKey.SetAttribute("field", "urn:schemas-microsoft-com:ehome:epg:airing#starttime");
                airingKey.InnerText = startTime.ToString("yyyy-MM-ddThh:mm:ssZ");
                airing.AppendChild(airingKey);
                programRecord.AppendChild(airing);
            }

            body.AppendChild(programRecord);
            clickToRecord.AppendChild(body);
            xmlDoc.AppendChild(clickToRecord);

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = Encoding.UTF8;
            settings.CloseOutput = false;
            settings.CheckCharacters = true;

            StringWriter stringWriter = new StringWriter();
            XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings); 
            //xmlWriter.WriteStartDocument();
            xmlDoc.WriteContentTo(xmlWriter);
            xmlWriter.Flush();
            string recordXmlString = stringWriter.ToString();
            Debug.Write(recordXmlString);
            xmlDoc = null;
            stringWriter = null;
            xmlWriter = null;

            XmlReader reader = XmlReader.Create(new StringReader(recordXmlString));
            request = null;

            CreateScheduleRequestResult scheduleResult = CreateScheduleRequestResult.NoConfiguredResource;
            try
            {
                EventSchedule scheduler = new EventSchedule();
                scheduleResult = scheduler.CreateScheduleRequest(reader, ConflictResolutionPolicy.AllowConflict, "MCE Media Manager Recording", out request);

                Debug.WriteLine("Application: RecordShow: " + scheduleResult);

                switch (scheduleResult)
                {
                    case CreateScheduleRequestResult.NotFound:
                        this.MessageBox(MCEMediaManager.Resources.TV_RecordingNotFoundDialog + "  " + ((programTitle == "") ? "" : programTitle + " : ") + ((serviceCallSign == "") ? "" : serviceCallSign + " : ") + ((startTime == null) ? "" : startTime.ToString("MM/dd/yyyy hh:mm tt")), MCEMediaManager.Resources.TV_RecordingNotFoundCaption, 1000, true);
                        break;
                    case CreateScheduleRequestResult.AlreadyScheduled:
                        this.MessageBox(MCEMediaManager.Resources.TV_RecordingAlreadyScheduledDialog + "  " + ((programTitle == "") ? "" : programTitle + " : ") + ((serviceCallSign == "") ? "" : serviceCallSign + " : ") + ((startTime == null) ? "" : startTime.ToString("MM/dd/yyyy hh:mm tt")), MCEMediaManager.Resources.TV_RecordingAlreadyScheduledCaption, 1000, true);
                        break;
                    case CreateScheduleRequestResult.ScheduledNoConflict:
                        this.MessageBox(MCEMediaManager.Resources.TV_RecordingSuccessfullyScheduledDialog + "  " + ((programTitle == "") ? "" : programTitle + " : ") + ((serviceCallSign == "") ? "" : serviceCallSign + " : ") + ((startTime == null) ? "" : startTime.ToString("MM/dd/yyyy hh:mm tt")), MCEMediaManager.Resources.TV_RecordingSuccessfullyScheduledCaption, 1000, true);
                        break;
                }
            }
            catch(EventScheduleException ex)
            {
                Application.Current.MessageBox(MCEMediaManager.Resources.TV_NotSetupDialog, MCEMediaManager.Resources.TV_NotSetupCaption + "  Exception : " + ex.Message,1000,true);
            }

            return scheduleResult;
        }

        public new void Dispose()
        {
            if (_MediaPlugins != null)
                _MediaPlugins = null;
            if (_TVDBData != null)
                _TVDBData = null;
        }

        #endregion

    }
}
